using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;

namespace Evaluant.EussDSL
{
    /// <summary>
    /// Additional behavior for a Rule to refresh the actual multiplicity
    /// of a Reference.
    /// </summary>
    public partial class RuleNew
    {
        internal sealed partial class parentFieldPropertyHandler
        {
            protected override void OnValueChanged(RuleNew element, string oldValue, string newValue)
            {
                base.OnValueChanged(element, oldValue, newValue);

                foreach (ModelElement me in element.Store.ElementDirectory.AllElements)
                {
                    if (me is ReferenceNewShape)
                    {
                        if (((ReferenceNewShape)me).ModelElement.Equals(element.ReferenceNew))
                        {
                            MultiplicityVerifier.VerifyReferenceNew((ReferenceNewShape)me, newValue, null);
                        }
                    }
                }

                //foreach (ModelElement me in element.Store.ElementDirectory.AllElements)
                //{
                //    if (me is ReferenceNewShape)
                //    {
                //        if (((ReferenceNewShape)me).ModelElement.Equals(element.ReferenceNew))
                //        {
                //            bool foundId = false;
                //            int index = -1, foundIdIndex = -1;
                //            switch (element.ReferenceNew.RulesNew.Count)
                //            {
                //                case 1: // potentially a 1..1 or 1..* relationship
                //                    foreach (Identifier id in element.ReferenceNew.Entity.Identifiers)
                //                    {
                //                        if (id.field == newValue)
                //                        {
                //                            foundId = true;
                //                        }
                //                    }
                //                    if (foundId)
                //                    { // 1..* relationship
                //                        foreach (LinkShape ls in ((ReferenceNewShape)me).Link)
                //                        {
                //                            if (ls is SourceNewConnector)
                //                            {
                //                                ((SourceNewConnector)ls).Multiplicity = "1";
                //                            }
                //                            if (ls is TargetNewConnector)
                //                            { // The TargetNewConnector has been created manually : it's the same for its decorator
                //                                AssociatedPropertyInfo propertyInfo = new AssociatedPropertyInfo(TargetNewConnector.MultiplicityDomainPropertyId);
                //                                propertyInfo.IsShapeProperty = true;
                //                                ((TargetNewConnector)ls).FindDecorator("MultiplicityDecorator").AssociateValueWith(((TargetNewConnector)ls).Store, propertyInfo);
                //                                ((TargetNewConnector)ls).Multiplicity = "*";
                //                            }
                //                        }
                //                    }
                //                    else
                //                    { // 1..1 relationship
                //                        foreach (LinkShape ls in ((ReferenceNewShape)me).Link)
                //                        {
                //                            if (ls is SourceNewConnector)
                //                            {
                //                                ((SourceNewConnector)ls).Multiplicity = "1";
                //                            }
                //                            if (ls is TargetNewConnector)
                //                            { // The TargetNewConnector has been created manually : it's the same for its decorator
                //                                AssociatedPropertyInfo propertyInfo = new AssociatedPropertyInfo(TargetNewConnector.MultiplicityDomainPropertyId);
                //                                propertyInfo.IsShapeProperty = true;
                //                                ((TargetNewConnector)ls).FindDecorator("MultiplicityDecorator").AssociateValueWith(((TargetNewConnector)ls).Store, propertyInfo);
                //                                ((TargetNewConnector)ls).Multiplicity = "1";
                //                            }
                //                        }
                //                    }
                //                    break;
                //                case 2: // potentially a *..* relationship
                //                    // one rule must have a parentField equals to an identifier field of the parent
                //                    // there are 2 RuleNew in element.ReferenceNew
                //                    index = (element.ReferenceNew.RulesNew[0] == element) ? 1 : 0; // index of the OTHER RuleNew
             
                //                    foreach (Identifier id in element.ReferenceNew.Entity.Identifiers)
                //                    {
                //                        if(newValue == id.field)
                //                        {
                //                            foundIdIndex = (index == 1)?0:1;
                //                        }
                //                        if(element.ReferenceNew.RulesNew[index].parentField == id.field)
                //                        {
                //                            foundIdIndex = index;
                //                        }
                //                    }

                //                    // the other rule must have a childField equals to an identifier of a target
                //                    bool foundChildField = false;
                //                    if(foundIdIndex >= 0)
                //                    {
                //                        foreach (LinkShape ls in ((ReferenceNewShape)me).Link)
                //                        {
                //                            if (ls is TargetNewConnector)
                //                            {
                //                                Entity toEntity = (Entity)(((TargetNewConnector)ls).ToShape.ModelElement);
                //                                foreach(Identifier id in toEntity.Identifiers)
                //                                {
                //                                    if(element.ReferenceNew.RulesNew[index].childField == id.field)
                //                                    {
                //                                        foundChildField = true;
                //                                    }
                //                                }
                //                            }
                //                        }
                                        
                //                        if(foundChildField)
                //                        {
                //                            foreach (LinkShape ls in ((ReferenceNewShape)me).Link)
                //                            {
                //                                if (ls is SourceNewConnector)
                //                                {
                //                                    ((SourceNewConnector)ls).Multiplicity = "*";
                //                                }
                //                                if (ls is TargetNewConnector)
                //                                { // The TargetNewConnector has been created manually : it's the same for its decorator
                //                                    AssociatedPropertyInfo propertyInfo = new AssociatedPropertyInfo(TargetNewConnector.MultiplicityDomainPropertyId);
                //                                    propertyInfo.IsShapeProperty = true;
                //                                    ((TargetNewConnector)ls).FindDecorator("MultiplicityDecorator").AssociateValueWith(((TargetNewConnector)ls).Store, propertyInfo);
                //                                    ((TargetNewConnector)ls).Multiplicity = "*";
                //                                }
                //                            }
                //                        }
                //                    }
                //                    if (foundIdIndex < 0 || !foundChildField)
                //                    {
                //                        foreach (LinkShape ls in ((ReferenceNewShape)me).Link)
                //                        {
                //                            if (ls is SourceNewConnector)
                //                            {
                //                                ((SourceNewConnector)ls).Multiplicity = "";
                //                            }
                //                            if (ls is TargetNewConnector)
                //                            { // The TargetNewConnector has been created manually : it's the same for its decorator
                //                                AssociatedPropertyInfo propertyInfo = new AssociatedPropertyInfo(TargetNewConnector.MultiplicityDomainPropertyId);
                //                                propertyInfo.IsShapeProperty = true;
                //                                ((TargetNewConnector)ls).FindDecorator("MultiplicityDecorator").AssociateValueWith(((TargetNewConnector)ls).Store, propertyInfo);
                //                                ((TargetNewConnector)ls).Multiplicity = "";
                //                            }
                //                        }
                //                    }
                //                    break;
                //                default: // unknown relationship
                //                    foreach (LinkShape ls in ((ReferenceNewShape)me).Link)
                //                    {
                //                        if (ls is SourceNewConnector)
                //                        {
                //                            ((SourceNewConnector)ls).Multiplicity = "";
                //                        }
                //                        if (ls is TargetNewConnector)
                //                        { // The TargetNewConnector has been created manually : it's the same for its decorator
                //                            AssociatedPropertyInfo propertyInfo = new AssociatedPropertyInfo(TargetNewConnector.MultiplicityDomainPropertyId);
                //                            propertyInfo.IsShapeProperty = true;
                //                            ((TargetNewConnector)ls).FindDecorator("MultiplicityDecorator").AssociateValueWith(((TargetNewConnector)ls).Store, propertyInfo);
                //                            ((TargetNewConnector)ls).Multiplicity = "";
                //                        }
                //                    }
                //                    break;
                //            }
                //        }
                //    }
                //}
            }
        }

        internal sealed partial class childFieldPropertyHandler
        {
            protected override void OnValueChanged(RuleNew element, string oldValue, string newValue)
            {
                base.OnValueChanged(element, oldValue, newValue);

                foreach (ModelElement me in element.Store.ElementDirectory.AllElements)
                {
                    if (me is ReferenceNewShape)
                    {
                        if (((ReferenceNewShape)me).ModelElement.Equals(element.ReferenceNew))
                        {
                            MultiplicityVerifier.VerifyReferenceNew((ReferenceNewShape)me, null, newValue);
                        }
                    }
                }
            }
        }
    }
}
